package com.douyin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.douyin.dto.FindPasswordDTO;
import com.douyin.dto.LoginDTO;
import com.douyin.dto.RegisterDTO;
import com.douyin.entity.Captcha;
import com.douyin.entity.User;
import com.douyin.exception.BaseException;
import com.douyin.properties.JwtProperties;
import com.douyin.service.ICaptchaService;
import com.douyin.service.IUserService;
import com.douyin.service.LoginService;
import com.douyin.utils.EmailUtil;
import com.douyin.utils.JwtUtil;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.ObjectUtils;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class LoginServiceImpl implements LoginService {
    @Autowired
    private ICaptchaService captchaService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private EmailUtil emailUtil;
    @Autowired
    private IUserService userService;
    @Autowired
    private JwtProperties jwtProperties;
    @Override
    public void getCaptcha(HttpServletResponse response, String uuId) throws IOException {
        if (ObjectUtils.isEmpty(uuId)) throw  new IllegalArgumentException("uuid不能为空");
        //将图片输出到response
        response.setHeader("Cache-Control","no-store, no-cache");
        response.setContentType("image/jpeg");
        //生成图形验证码图片
        BufferedImage image = captchaService.generateCaptcha(uuId);
        ServletOutputStream outputStream =response.getOutputStream();
        ImageIO.write(image,"jpg",outputStream);
        IOUtils.closeQuietly(outputStream);
    }

    @Override
    public boolean getCode(Captcha captcha) {
        if (captchaService.isValidate(captcha)){
            String code = getSixCode();
            stringRedisTemplate.opsForValue().set("emailCode:"+captcha.getEmail(),code,5L, TimeUnit.MINUTES);
            emailUtil.sendMail(captcha.getEmail(),"验证码","验证码为："+code+" ，时效为5分钟，请勿泄露！");
            return true;
        }
        return false;
    }

    @Override
    public void checkCode(String email, Integer code) {
        if (ObjectUtils.isEmpty(email) || ObjectUtils.isEmpty(code)) throw  new BaseException("参数不能为空");
        String redisCode = stringRedisTemplate.opsForValue().get("emailCode:"+email);
        if (!code.toString().equals(redisCode)){
            throw  new BaseException("邮箱验证码错误");
        }
    }

    @Override
    public void register(RegisterDTO registerDTO) {
        if (!userService.register(registerDTO)){
            throw  new BaseException("注册失败");
        }
    }

    @Override
    public Map<String, Object> login(LoginDTO loginDTO) {
        Map<String, Object> result = new HashMap<>();
        User user =new User();
        BeanUtils.copyProperties(loginDTO,user);
        String password = DigestUtils.md5DigestAsHex(loginDTO.getPassword().getBytes());
        user = userService.getOne(new LambdaQueryWrapper<User>().eq(User::getEmail,user.getEmail()));
        if (user == null){
            throw new BaseException("用户不存在");
        }
        if(!password.equals(user.getPassword())){
            throw new BaseException("密码错误");
        }
        Map<String, Object> claims = new HashMap<>();
        claims.put("userId",user.getId());
        String token = JwtUtil.createJWT(jwtProperties.getSecretKey(), jwtProperties.getTtl(), claims);
        result.put("token",token);
        result.put("user",user);
        result.put("name",user.getNickName());
        return result;
    }

    @Override
    public void findPassword(FindPasswordDTO findPasswordDTO) {
        if (ObjectUtils.isEmpty(findPasswordDTO.getEmail()) || ObjectUtils.isEmpty(findPasswordDTO.getCode()))
            throw  new BaseException("参数不能为空");
        String redisCode = stringRedisTemplate.opsForValue().get("emailCode:"+findPasswordDTO.getEmail());
        if (ObjectUtils.isEmpty(redisCode)){
            throw  new BaseException("验证码已过期");
        }
        if (!findPasswordDTO.getCode().toString().equals(redisCode)){
            throw  new BaseException("邮箱验证码错误");
        }
        User user = new User();
        user.setEmail(findPasswordDTO.getEmail());
        user.setPassword(DigestUtils.md5DigestAsHex(findPasswordDTO.getNewPassword().getBytes()));
        userService.update(user,new UpdateWrapper<User>().lambda()
                .set(User::getPassword,user.getPassword())
                .eq(User::getEmail,user.getEmail()));
    }


    public static String getSixCode(){
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < 6; i++) {
            int code = (int) (Math.random()*10);
            builder.append(code);
        }
        return builder.toString();
    }
}
